package net.blogjava.mobile.widget;

import java.io.File;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import net.blogjava.mobile.Main;
import net.blogjava.mobile.R;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class FileBrowser extends ListView implements
		android.widget.AdapterView.OnItemClickListener,
		android.widget.AdapterView.OnItemSelectedListener {
	private final String namespace = "http://mobile.blogjava.net";
	private String sdcardDirectory;
	private List<File> fileList = new ArrayList<File>();
	private Stack<String> dirStack = new Stack<String>();
	private FileListAdapter fileListAdapter;
	private OnFileBrowserListener onFileBrowserListener;
	private int folderImageResId;
	private int neighborhoodImageResId;	
	private int otherFileImageResId;
	public Map<String, Integer> fileImageResIdMap = new HashMap<String, Integer>();
	private boolean onlyFolder = false;
	private int currentFileType = 0; // 0 folder , 1 video , 2 picture , 3 audio , 4 apk

	public int curPosition = 0;
	public String lanPath = "";
	public boolean needLanScan = true;
	public boolean allowLanScan = true;
	static final String LANREQ = "com.pclink.lan.req.msg";
	public String lanMountPoint = "/mnt/networkNeighborhood";
	public String pathString = "PATH";
	public String cmdString = "CMD";
	public String statusString = "STATUS";
	public String laninit = "laninit";
	public String lanscan = "lanscan";
	public String lanenter = "lanenter";

	public FileBrowser(Context context, AttributeSet attrs) {
		super(context, attrs);
		sdcardDirectory = "/mnt";// android.os.Environment.getExternalStorageDirectory().toString();
		setOnItemClickListener(this);
		setOnItemSelectedListener(this);

		setBackgroundColor(android.graphics.Color.BLACK);

		folderImageResId = attrs.getAttributeResourceValue(namespace,
				"folderImage", 0);
		neighborhoodImageResId = attrs.getAttributeResourceValue(namespace,
				"neighborhoodImage", 0);
		
		otherFileImageResId = attrs.getAttributeResourceValue(namespace,
				"otherFileImage", 0);
		onlyFolder = attrs.getAttributeBooleanValue(namespace, "onlyFolder",
				false);
		int index = 1;
		while (true) {
			String extName = attrs.getAttributeValue(namespace, "extName"
					+ index);
			int fileImageResId = attrs.getAttributeResourceValue(namespace,
					"fileImage" + index, 0);

			if ("".equals(extName) || extName == null || fileImageResId == 0) {
				break;
			}
			fileImageResIdMap.put(extName, fileImageResId);
			index++;
		}

		dirStack.push(sdcardDirectory);
		//dirStack.push("mnt");
		addFiles();

		// LinearLayout.LayoutParams param3 = new LinearLayout.LayoutParams(50,
		// 50);
		// param3.setMargins(0, 0, 0, 0);
		// this.setLayoutParams(param3);

		// this.setPadding(0,0, 100, 0);
		fileListAdapter = new FileListAdapter(getContext());
		setAdapter(fileListAdapter);
	}

	public void updateStorageDir() {
		String currentPath = getCurrentPath();
		if (currentPath.length() < 4)
			return;

		if (currentPath.substring(0, 4).equalsIgnoreCase("/mnt")) {
			Log.d("========updateStorageDir======", "in");

			addFiles();
			fileListAdapter.notifyDataSetChanged();
		}
	}

	private void addFiles() {

		fileList.clear();
		String currentPath = getCurrentPath();
		File[] files = new File(currentPath).listFiles();
		if (dirStack.size() > 1)
			fileList.add(null);

		if (files == null) {
			Log.w("=======", "null");
		} else {
			List<File> tempList = new ArrayList<File>();

			for (File file : files) {
				// if (onlyFolder)
				if (file.isDirectory()) {
					fileList.add(file);
				} else {
					String extName = getExtName(file.getName());
					// Log.d("===========extName===========",extName);
					Integer resId = fileImageResIdMap.get(extName);
					if (resId != null)
						tempList.add(file);
				}
			}

			fileList.addAll(tempList);
		}
	}

	private String getCurrentPath() {
		String path = "";
		for (String dir : dirStack) {
			path += dir + "/";
		}
		path = path.substring(0, path.length() - 1);
		path = path.replace("//", "/");
		return path;
	}

	public String getExtName(String filename) {

		int position = filename.lastIndexOf(".");
		if (position >= 0) {
			String extName = filename.substring(position + 1);
			return extName.toLowerCase();
		} else {
			return "";
		}
	}

	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		goNextDirectory(position);
	}

	public void onItemSelected(AdapterView<?> parent, View view, int position,
			long id) {
		// ListView listView = (ListView) parent;
		// Log.w("==position===", String.valueOf(position));
		// Log.w("Test", "id = " + id + "(" +
		// listView.getSelectedItem().toString() + ")");
		File file = fileList.get(position);

		Main app = (Main) onFileBrowserListener;
		if (file != null) {
			long lastModifyDate = file.lastModified();
			Date date = new Date(lastModifyDate);
			// Log.w("======date====",date.toLocaleString());
			app.fileDate.setText(app.dateStr + date.toLocaleString());

			if (file.isFile()) {
				long length = file.length();
				app.fileSize.setText(app.sizeStr + getFileSize(length));
				String extName = getExtName(file.getName());
				Integer resId = fileImageResIdMap.get(extName);
				if (resId != null) {
					switch (resId) {
					case R.drawable.video:
						if (currentFileType != 1) {
							app.imgFile.setImageResource(R.drawable.moviepost);
							currentFileType = 1;
						}
						break;
					case R.drawable.jpg:
						if (currentFileType != 2) {
							app.imgFile.setImageResource(R.drawable.picpost);
							currentFileType = 2;
						}
						break;
					case R.drawable.audio:
						if (currentFileType != 3) {
							app.imgFile.setImageResource(R.drawable.musicpost);
							currentFileType = 3;
						}
						break;
					case R.drawable.apk:
						if (currentFileType != 4) {
							app.imgFile.setImageResource(R.drawable.folderpost);
							currentFileType = 4;
						}
						break;
					}
				}
			} else {
				if (currentFileType != 0) {
					app.imgFile.setImageResource(R.drawable.folderpost);
					currentFileType = 0;
				}
			}
		}
	};

	public String getFileSize(long size) {

		if (size < 1024)
			return (String.valueOf(size) + "B");

		DecimalFormat df = new DecimalFormat("###.##");
		float f;
		if (size < 1024 * 1024) {
			f = (float) ((float) size / (float) 1024);
			return (df.format(new Float(f).doubleValue()) + "KB");
		} else {
			f = (float) ((float) size / (float) (1024 * 1024));
			return (df.format(new Float(f).doubleValue()) + "MB");
		}
	}

	public void onNothingSelected(AdapterView<?> parent) {
	};

	public void setOnFileBrowserListener(OnFileBrowserListener listener) {
		this.onFileBrowserListener = listener;
	}

	public void goPrevDirectory() {
		String currentDirectory = dirStack.pop();
		Log.w("====dir===", currentDirectory);
		addFiles();
		fileListAdapter.notifyDataSetChanged();

		for (int i = 0; i < fileList.size(); i++) {
			if (fileList.get(i) != null) {
				if (currentDirectory.equals(fileList.get(i).getName())) {
					this.setSelection(i);
					break;
				}
			}
		}

		// this.setSelection(0);

		if (onFileBrowserListener != null) {
			onFileBrowserListener.onDirItemClick(getCurrentPath());
		}
	}

	public void goPausedDirectory() {
		System.out.println("goPausedDirectory, position: " + curPosition);
		goNextDirectory(curPosition);
	}

	public void goLan(String str1, String str2) {
		System.out.println("goLan " + allowLanScan);
		if (!allowLanScan)
			return;
		allowLanScan = false;

		Main app = (Main) onFileBrowserListener;
		System.out.println("goLan "+str1+":"+str2);
		Intent intent = new Intent(LANREQ);
		Bundle bundle = new Bundle();

		if (str1.length() == 0)
			bundle.putString(cmdString, laninit);
		else
			bundle.putString(cmdString, str1);

		bundle.putString(pathString, str2);
		intent.putExtras(bundle);
		app.sendBroadcast(intent);
	}

	public void goNextDirectory(int position) {
		curPosition = position;
		if (fileList.get(position) == null) {
			goPrevDirectory();
		} else if (fileList.get(position).isDirectory()) {

			String targetPath = getCurrentPath()+"/"+fileList.get(position).getName();

			System.out.println(lanPath+"::"+targetPath+"::"+lanMountPoint);

			if (!targetPath.equals(lanPath) && targetPath.startsWith(lanMountPoint))
			{
				if (targetPath.equals(lanMountPoint))
				{
					if (needLanScan)
					{
						goLan(lanscan, targetPath);
						return;
					}
				}
				else
				{
					String folderlist[] = targetPath.split("/");
					if (folderlist.length == 3+1)  //Null filtering. Fix me
					{
						lanPath = targetPath;
						goLan(lanenter, targetPath);
						return;
					}
				}
			}

			dirStack.push(fileList.get(position).getName());
			addFiles();
			fileListAdapter.notifyDataSetChanged();
			if (onFileBrowserListener != null) {
				onFileBrowserListener.onDirItemClick(getCurrentPath());
			}
		} else {
			if (onFileBrowserListener != null) {
				String filePath = getCurrentPath() + "/"
						+ fileList.get(position).getName();
				filePath = filePath.replace("//", "/");
				onFileBrowserListener.onFileItemClick(filePath);
			}
		}
	}

	public void restoreMe(Bundle state) {
		
		if (state==null)
			return;
		
		String currentFilePath=state.getString("currentFilePath");
		if (currentFilePath==null)
			return;
		
		Log.d("====restoreMe===", "start");
		dirStack.clear();

		if (currentFilePath.equals("/")) {
			dirStack.add(currentFilePath);
		} else {
			String path[] = currentFilePath.split("/");
			for (int i = 0; i < path.length - 1; i++) {
				String element = path[i];
				if (element.length() == 0)
					element = "/";
				dirStack.add(element);
			}
		}
		addFiles();
		onFileBrowserListener.onDirItemClick(currentFilePath);
		Log.d("====restoreMe===", "end");
	}

	public boolean onKeyDown(int keyCode, KeyEvent event) {

		super.onKeyDown(keyCode, event);
		Log.w("=======", "you pressed key:" + String.valueOf(keyCode));

		switch (keyCode) {
		case KeyEvent.KEYCODE_DPAD_LEFT: // Left 21
			if (dirStack.size() > 1) {
				goPrevDirectory();
			}
			break;
		case KeyEvent.KEYCODE_DPAD_RIGHT: // Right 22
		{
			Log.w("===pos===", String.valueOf(this.getSelectedItemPosition()));
			int position = this.getSelectedItemPosition();
			goNextDirectory(position);
		}
			break;
		}

		return false;
	}

	private class FileListAdapter extends BaseAdapter {
		private Context context;

		public FileListAdapter(Context context) {
			this.context = context;
		}

		public int getCount() {
			return fileList.size();
		}

		public Object getItem(int position) {
			return fileList.get(position);
		}

		public long getItemId(int position) {
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			// Log.w("====", String.valueOf(position));
			LinearLayout fileLayout = new LinearLayout(context);
			fileLayout.setLayoutParams(new LayoutParams(// LayoutParams.WRAP_CONTENT,
					LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
			fileLayout.setOrientation(LinearLayout.HORIZONTAL);
			// fileLayout.setPadding(40, 10, 0, 10);
			fileLayout.setPadding(40, 0, 0, 0);
			ImageView ivFile = new ImageView(context);
			ivFile.setLayoutParams(new LayoutParams(48, 48));
			TextView tvFile = new TextView(context);
			tvFile.setTextColor(android.graphics.Color.WHITE);
			tvFile.setTextAppearance(context,
					android.R.style.TextAppearance_Large);

			tvFile.setPadding(5, 5, 0, 0);
			if (fileList.get(position) == null) {
				if (folderImageResId > 0)
					ivFile.setImageResource(folderImageResId);
				tvFile.setText(". .");
			} else if (fileList.get(position).isDirectory()) {
				if (folderImageResId > 0)
					ivFile.setImageResource(folderImageResId);
				
				if (lanMountPoint.equals(fileList.get(position)
						.getAbsolutePath())) {
					if (neighborhoodImageResId > 0)
						ivFile.setImageResource(neighborhoodImageResId);
				}
				tvFile.setText(fileList.get(position).getName());
			} else {
				tvFile.setText(fileList.get(position).getName());
				Integer resId = fileImageResIdMap.get(getExtName(fileList.get(
						position).getName()));
				int fileImageResId = 0;
				if (resId != null) {
					if (resId > 0) {
						fileImageResId = resId;
					}
				}
				if (fileImageResId > 0)
					ivFile.setImageResource(fileImageResId);
				else if (otherFileImageResId > 0)
					ivFile.setImageResource(otherFileImageResId);
			}

			tvFile.setLayoutParams(new LayoutParams(// LayoutParams.WRAP_CONTENT,
					LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
			fileLayout.addView(ivFile);
			fileLayout.addView(tvFile);

			return fileLayout;
		}
	}
}
